package util;

import io.javalin.http.UploadedFile;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.UUID;
import org.apache.commons.io.FilenameUtils;

public class FileStorageUtil {
    private static final String STORAGE_ROOT = "storage";
    private static final String MUSIC_DIR = "music";
    private static final String SYSTEM_DIR = "system";
    private static final String USERS_DIR = "users";
    private static final String COVERS_DIR = "covers";
    private static final String DATA_DIR = "src/data";
    private static final String LYRIC_DIR = "lyrics";
    
    public static String getSystemMusicPath(String artist, String filename) {
        return String.format("%s/%s/%s/%s/%s", 
            STORAGE_ROOT, MUSIC_DIR, SYSTEM_DIR, artist, filename);
    }
    
    public static String getUserMusicPath(Long userId, String filename) {
        String yearMonth = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
        return String.format("%s/%s/%s/%d/%s/%s",
            STORAGE_ROOT, MUSIC_DIR, USERS_DIR, userId, yearMonth, filename);
    }
    
    public static String getSystemCoverPath(String filename) {
        return String.format("%s/%s/%s/%s", 
            STORAGE_ROOT, COVERS_DIR, SYSTEM_DIR, filename);
    }
    
    public static String getUserCoverPath(Long userId, String filename) {
        String yearMonth = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
        return String.format("%s/%s/%s/%d/%s/%s",
            STORAGE_ROOT, COVERS_DIR, USERS_DIR, userId, yearMonth, filename);
    }
    
    public static String getPlaylistCoverPath(Long playlistId, String filename) {
        return String.format("%s/%s/playlists/%d/%s",
            STORAGE_ROOT, COVERS_DIR, playlistId, filename);
    }
    
    public static void createDirectories(String path) throws IOException {
        Path dirPath = Paths.get(path).getParent();
        if (dirPath != null) {
            Files.createDirectories(dirPath);
        }
    }
    
    public static String generateUniqueFilename(String originalFilename) {
        String extension = FilenameUtils.getExtension(originalFilename);
        String uuid = UUID.randomUUID().toString();
        return String.format("%s.%s", uuid, extension);
    }
    
    public static void initStorageStructure() throws IOException {
        // 创建基本目录结构
        createDirectories(STORAGE_ROOT + "/" + MUSIC_DIR + "/" + SYSTEM_DIR);
        createDirectories(STORAGE_ROOT + "/" + MUSIC_DIR + "/" + USERS_DIR);
        createDirectories(STORAGE_ROOT + "/" + COVERS_DIR + "/" + SYSTEM_DIR);
        createDirectories(STORAGE_ROOT + "/" + COVERS_DIR + "/" + USERS_DIR);
        createDirectories(STORAGE_ROOT + "/" + LYRIC_DIR + "/" + SYSTEM_DIR);
        createDirectories(STORAGE_ROOT + "/" + LYRIC_DIR + "/" + USERS_DIR);
    }

    public static String getDataDir() {
        return DATA_DIR;
    }
    
    public static String saveMusicFile(InputStream content, String filename, Long userId) throws IOException {
        String relativePath = getUserMusicPath(userId, filename);
        saveFile(content, relativePath);
        return relativePath;
    }
    
    public static String saveCoverFile(InputStream content, String filename, Long userId) throws IOException {
        String relativePath = getUserCoverPath(userId, filename);
        saveFile(content, relativePath);
        return relativePath;
    }
    
    public static String saveLyricFile(InputStream content, String filename, Long userId) throws IOException {
        String relativePath = getUserLyricPath(userId, filename);
        saveFile(content, relativePath);
        return relativePath;
    }
    
    public static String saveMusicFile(UploadedFile file, Long userId) throws IOException {
        ValidationUtil.validateAudioFile(file);
        String filename = generateUniqueFilename(file.getFilename());
        return saveMusicFile(file.getContent(), filename, userId);
    }
    
    public static String saveCoverFile(UploadedFile file, Long userId) throws IOException {
        ValidationUtil.validateImageFile(file);
        String filename = generateUniqueFilename(file.getFilename());
        return saveCoverFile(file.getContent(), filename, userId);
    }
    
    public static String saveLyricFile(UploadedFile file, Long userId) throws IOException {
        if (file == null) return null;
        ValidationUtil.validateLyricFile(file);
        String filename = generateUniqueFilename(file.getFilename());
        return saveLyricFile(file.getContent(), filename, userId);
    }
    
    public static void deleteFile(String path) throws IOException {
        if (path != null) {
            Files.deleteIfExists(Paths.get(path));
        }
    }
    
    public static void saveFile(InputStream content, String relativePath) throws IOException {
        createDirectories(relativePath);
        Files.copy(content, Paths.get(relativePath), StandardCopyOption.REPLACE_EXISTING);
    }
    
    public static String getUserLyricPath(Long userId, String filename) {
        String yearMonth = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
        return String.format("%s/%s/%s/%d/%s/%s",
            STORAGE_ROOT, LYRIC_DIR, USERS_DIR, userId, yearMonth, filename);
    }
}